package com.huajx.core.udp;

import com.huajx.core.config.HbootConfigManager;
import com.huajx.core.udp.annonation.MinaClient;
import com.huajx.core.udp.config.UDPClientConfig;
import com.huajx.util.ClassUtil;
import com.huajx.util.ObjectUtil;
import com.huajx.util.ReflectUtil;
import com.huajx.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * @program: di-parent
 * @description:
 * @author: lisa 叶新华
 * @create: 2019-09-26 13:02
 */
public class UDPClientManager {
    private final Logger logger = LoggerFactory.getLogger(UDPClientManager.class);

    private final static UDPClientManager manager = new UDPClientManager();

    private final static Map<String, UDPClientInfo> clientInfos = new LinkedHashMap<>();
    private final static Map<String, UDPClient> clients = new LinkedHashMap<>();

    public static UDPClientManager me() {
        return manager;
    }

    /**
     * 扫描所有HbootServer子类
     */
    public void scan() {
        logger.debug("服务扫描开始");
        Set<Class<?>> classes = ClassUtil.scanPackageBySuper(null, UDPClient.class);

        UDPClientConfig config = null;

        MinaClient client = null;

        logger.debug("Scan UDPClient ");
        for (Class<?> clazz : classes) {
            Class<UDPClient> clientClass = (Class<UDPClient>) clazz;

            client = clientClass.getAnnotation(MinaClient.class);

            if (client == null) {
                continue;
            }

            String clientName = client.name();

            if (StrUtil.isBlank(clientName)) {
                clientName = StrUtil.lowerFirst(clazz.getSimpleName());
            }

//            logger.info("正在启动服务: {}", serverName);
            UDPClientInfo info = new UDPClientInfo();

            info.setName(clientName);
            info.setPort(client.port());
            info.setClientClass(clientClass);

            clientInfos.put(clientName, info);

        }
        logger.debug("服务扫描结束");
    }

    public void start() {
//        ExecutorService executor;
        if (ObjectUtil.notEmpty(clients)) {
            for (Map.Entry<String, UDPClient> serverEntry : clients.entrySet()) {

                UDPClient server = serverEntry.getValue();
                if (server == null) {
                    continue;
                }
                if (!server.isRunning()) {
                    server.start();
                }

                logger.info("{}客户端启动成功!", serverEntry.getKey());
            }

            return;
        }

        int size = clientInfos.size();
//        executor = Executors.newFixedThreadPool(size);

        for (Map.Entry<String, UDPClientInfo> entry : clientInfos.entrySet()) {
            String key = entry.getKey();

            UDPClientInfo info = entry.getValue();
            Class<? extends UDPClient> clazz = info.getClientClass();

            String name = info.getName();
            int port = info.getPort();

            Map<String, UDPClientConfig> configs = HbootConfigManager.me().get(UDPClientConfig.class, key);

            for (Map.Entry<String, UDPClientConfig> configEntry : configs.entrySet()) {


                UDPClientConfig config = configEntry.getValue();

                if (config.getPort() <= 80) {
                    config.setPort(port);
                }

                if (StrUtil.isBlank(config.getName())) {
                    config.setName(name);
                }

                String configName = configEntry.getKey();

//                logger.info("{}正在启动服务,{}", name, port);
                UDPClient client = ReflectUtil.newInstance(clazz);
                client.config(config);
                client.start();

                clients.put(configName, client);

                logger.info("{}:{} {}启动成功!", config.getIp(), config.getPort(), config.getName());
            }
//            logger.info("配置信息:{}", configs);
        }
//        logger.info("所有服务，启动完毕");

    }

    public void stop() {
        for (Map.Entry<String, UDPClient> serverEntry : clients.entrySet()) {
            UDPClient server = serverEntry.getValue();
            if (server == null) {
                continue;
            }
            if (server.isRunning()) {
                server.stop();
            }
        }
    }
}
